#include "app_user_interface.h"
#include "app_motion_control.h"

// 设备驱动调用
#include "device.h"
extern device_t device;
static key_t *key = &device.key;
static oled_t *oled = &device.oled;
static buzzer_t *buzzer = &device.buzzer;

// 算法库调用
#include "algorithm.h"
extern algo_imu_t algo_imu;
extern algo_pid_t algo_pid_pitch_angle;	// 飞行器俯仰角度PID
extern algo_pid_t algo_pid_roll_angle;	// 飞行器横滚角度PID
extern algo_pid_t algo_pid_yaw_angle;	// 飞行器偏航角度PID
extern algo_pid_t algo_pid_pitch_gyro; 	// 飞行器俯仰角速度PID
extern algo_pid_t algo_pid_roll_gyro;	// 飞行器横滚角速度PID
extern algo_pid_t algo_pid_yaw_gyro;	// 飞行器偏航角速度PID

// 变量初始化
// debug界面
parameter_t parameter[PARA_LINE_MAX * PARA_PAGE_MAX] = 
{
	// page0
	{PATA_FLOAT, "kp", 0, 0, &algo_pid_roll_angle.kp, 0.1},
	{PATA_FLOAT, "ki", 0, 0, &algo_pid_roll_angle.ki, 0.01},
	{PATA_FLOAT, "kd", 0, 0, &algo_pid_roll_angle.kd, 1},
	{PARA_INT, "motor_basic", &g_motion_control.motor_control.motor_pwm_basic, 10, 0, 0},
	{PARA_INT, "motor0", &g_motion_control.motor_control.motor_total[0], 0, 0, 0},
	{PARA_INT, "motor1", &g_motion_control.motor_control.motor_total[1], 0, 0, 0},
	{PARA_INT, "motor2", &g_motion_control.motor_control.motor_total[2], 0, 0, 0},
	{PARA_INT, "motor3", &g_motion_control.motor_control.motor_total[3], 0, 0, 0},
	// page1
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	// page2
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
};

// basic界面
parameter_t parameter_basic[PARA_LINE_MAX] = 
{
	{PARA_INT, "pitch_cur", (int16*)&g_motion_control.posture_control.cur_pitch_angle, 0, 0, 0},
	{PARA_INT, "roll_cur", (int16*)&g_motion_control.posture_control.cur_roll_angle, 0, 0, 0},
	{PARA_INT, "yaw_cur", (int16*)&g_motion_control.posture_control.cur_yaw_angle, 0, 0, 0},
	{PARA_NULL, "null", 0, 0, 0, 0},
	{PARA_INT, "motor0", &g_motion_control.motor_control.motor_total[0], 0, 0, 0},
	{PARA_INT, "motor1", &g_motion_control.motor_control.motor_total[1], 0, 0, 0},
	{PARA_INT, "motor2", &g_motion_control.motor_control.motor_total[2], 0, 0, 0},
	{PARA_INT, "motor3", &g_motion_control.motor_control.motor_total[3], 0, 0, 0},
};

debug_lock_e g_debug_lock = LOCKED;
buzzer_state_e g_buzzer_state = BUZZER_OFF;
uint8 g_page_ptr = 0, g_line_ptr = 0;


// 功能选择
static void func_select(void)
{
	uint8 key_value = 0, para_ptr = 0;
	key_value = key->scan(0);
	para_ptr = g_page_ptr * PARA_LINE_MAX + g_line_ptr;
	
	// 参数调整
	if (g_debug_lock == UNLOCKED)
	{
		switch (key_value)
		{
			case KEY0_ON:
				oled->clear();
				++g_line_ptr;
				if (g_line_ptr >= PARA_LINE_MAX) g_line_ptr = 0;
				break;
			case KEY1_ON:
				if (parameter[para_ptr].type != PARA_NULL)
				{
					if (parameter[para_ptr].type == PARA_INT)
						(*parameter[para_ptr].int_value) -= parameter[para_ptr].delta_debug_int;
					else if (parameter[para_ptr].type == PATA_FLOAT)
						(*parameter[para_ptr].float_value) -= parameter[para_ptr].delta_debug_float;
				}
				break;
			case KEY2_ON:
				if (parameter[para_ptr].type != PARA_NULL)
				{
					if (parameter[para_ptr].type == PARA_INT)
						(*parameter[para_ptr].int_value) += parameter[para_ptr].delta_debug_int;
					else if (parameter[para_ptr].type == PATA_FLOAT)
						(*parameter[para_ptr].float_value) += parameter[para_ptr].delta_debug_float;
				}
				break;
			case KEY3_ON:
				oled->clear();
				++g_page_ptr;
				if (g_page_ptr >= PARA_PAGE_MAX) g_page_ptr = 0;
				break;
		}
	}
}

// 界面显示
static void interface_display(void)
{
	static uint8 last_debug_lock = LOCKED;
	uint8 line = 0, para = 0;
	
	if (last_debug_lock != g_debug_lock)
	{
		last_debug_lock = g_debug_lock;
		oled->clear();
	}
	
	switch (g_debug_lock)
	{
		case LOCKED:
			for (line = 0; line < PARA_LINE_MAX; ++line)
			{
				if (parameter_basic[line].type != PARA_NULL)
				{
					oled->show_str(0, line, parameter_basic[line].name);
					if (parameter_basic[line].type == PARA_INT)
						oled->show_value_int(6*12, line, *parameter_basic[line].int_value);
					else if (parameter_basic[line].type == PATA_FLOAT)
						oled->show_value_float(6*12, line, *parameter_basic[line].float_value, 2);
				}
			}
			break;
		
		case UNLOCKED:
			for (line = 0; line < PARA_LINE_MAX; ++line)
			{
				para = g_page_ptr * PARA_LINE_MAX + line;
				if (parameter[para].type != PARA_NULL)
				{
					oled->show_str(0, line, parameter[para].name);
					if (parameter[para].type == PARA_INT)
						oled->show_value_int(6*12, line, *parameter[para].int_value);
					else if (parameter[para].type == PATA_FLOAT)
						oled->show_value_float(6*12, line, *parameter[para].float_value, 2);
				}
			}
			oled->show_str(110, g_line_ptr, "<-");
			break;
	}
	
	
}

// 消息提醒（此函数用于中断中）
// 蜂鸣器，LED灯等提示
// timer_frequency: 定时器工作频率
static void message_alerts(uint32 timer_frequency)
{
	static uint8 last_debug_lock = LOCKED;
	static uint16 t = 0;
	const uint16 cnt_500ms = timer_frequency / 2; 	// 0.5s计数
	const uint16 cnt_1s = timer_frequency; 			// 1s计数
	const uint16 cnt_5s = timer_frequency * 5; 		// 5s计数
	
	// 调试状态切换提醒
	if (last_debug_lock != g_debug_lock)
	{
		last_debug_lock = g_debug_lock;
		g_buzzer_state = BUZZER_ON_500MS; // 从基本界面切换到参数调试界面，蜂鸣器短响
	}
	
	// 起飞消息提醒
	if (g_motion_control.state == WAIT)
	{
		g_buzzer_state = BUZZER_BEEP_5S;
	}
	
	// 蜂鸣器工作
	switch (g_buzzer_state)
	{
		case BUZZER_OFF:
			t = 0;
			buzzer->beep(timer_frequency, 0);
			break;
		case BUZZER_ON_500MS:
			buzzer->beep(timer_frequency,timer_frequency);
			++t;
			if (t >= cnt_500ms) g_buzzer_state = BUZZER_OFF;
			break;
		case BUZZER_ON_1S:
			buzzer->beep(timer_frequency,timer_frequency);
			++t;
			if (t >= cnt_1s) g_buzzer_state = BUZZER_OFF;
			break;
		case BUZZER_BEEP_5S:
			buzzer->beep(timer_frequency,timer_frequency / 2);
			++t;
			if (t >= cnt_5s) g_buzzer_state = BUZZER_OFF;
			break;
	}
}

// 调试模式切换（此函数用于中断中）
// timer_frequency: 定时器工作频率
static void debug_mode_switch(uint32 timer_frequency)
{
	// 按键0和按键3同时按下2秒后切换调试模式
	if (key->tim_scan(timer_frequency, 2, KEY0_ON | KEY3_ON))
	{
		if (g_debug_lock == LOCKED)
			g_debug_lock = UNLOCKED;
		else
			g_debug_lock = LOCKED;
	}
	// 在basic模式下按键0按下2秒后，四轴起飞
	if (g_debug_lock == LOCKED) 
	{
		if (key_tim_scan(timer_frequency, 2, KEY0_ON))
		{
			g_motion_control.state = WAIT;
		}
	}
}

// 用户交互定时器中断处理（此函数用于中断中）
// timer_frequency: 定时器工作频率
void user_interface_tim_handle(uint32 timer_frequency)
{
	key->tim_check(timer_frequency, 1); // 按键长按检测，按键按下一秒后视为长按触发
	debug_mode_switch(timer_frequency);	// 调试模式切换，切换界面状态，一键起飞
	message_alerts(timer_frequency);	// 消息提醒，蜂鸣器，LED闪烁
}

// 用户交互接口
void user_interface(void)
{
	func_select();			// 调试功能选择
	interface_display();	// 界面显示
}

